#ifndef STATE_HPP
#define STATE_HPP

#ifdef USE_OPENMP
#include <omp.h>
#elif  USE_MPI
#include <mpi.h>
#elif  USE_SHMEM
#include <dislib.h>
#endif

#include "conversion.h"
#include "bit.h"
#include "process.h"
#include "random.h"

#include <iostream>
#include <fstream>
#include <complex>
#include <unistd.h>

#define SIZE_BLOCK 1024*1024

typedef std::complex<double> complexd;

using namespace std;

class State : public Process {
    int common_dimension, dimension;
    long long common_length, length;
    long long begin, end, size_block;
    complexd* vec;

    int what_is_index(long long);
    int power_2(long long);
    void define_size();
public:
    int what_is_rank(long long);

    State(int, int argc = 0, char *argv[] = 0);
    State(const State &);
    ~State();

    void randomFill();
    void intentionalFill(long long, complexd * );

    void doConversion(Conversion &, int);
    void nConversion(Conversion &, double);
    void n0Conversion(Conversion &);
    void norma();

    long long getLong();
    int getDimension();

    void output(char *);
    void input(char *);

    long long getMyLong();
    complexd* getMyVector();
    int getMyDimension();

    void info();

    State operator=(State);
    bool operator==(State);
    bool operator!=(State);

    complexd operator*(State);

    friend ostream& operator<<(ostream &, State &);
    friend istream& operator>>(istream &, State &);
};


#endif // STATE_HPP
